import type { VarTypes } from '@/types/common'
import { FatalError } from './customError'

export function getVarType(value: any) {
  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase() as VarTypes
}

const rawHasOwnProperty = Object.prototype.hasOwnProperty

export function hasOwnProperty(obj: any, key: string) {
  return rawHasOwnProperty.call(obj, key)
}

/**
 * 创建失败重试方法
 * @param fn
 * @param retryCount
 * @returns
 */
export function createFailRetryMethod<A extends any[], R>(
  fn: (...args: A) => Promise<R>,
  retryCount: number,
  callback?: (error: unknown) => void | true | Error
): (...args: A) => Promise<R> {
  if (retryCount < 0) retryCount = 0
  retryCount += 1
  if (!callback) callback = () => {}

  return async (...args: A) => {
    for (let i = 0; i < retryCount; i++) {
      try {
        return await fn(...args)
      } catch (error) {
        const r = callback(error)
        if (r === true) throw error
        if (r instanceof Error) throw r
        if (FatalError.isFatalError(error)) throw error
        if (i >= retryCount) throw error
      }
    }
    throw new FatalError('Not Executed')
  }
}

export const sleep = (ms = 0) => new Promise((resolve) => setTimeout(resolve, ms))
